//using System.Drawing;

//also called mexican hat
//**
// * The laplacian of Gaussian operator code.
// *
// * @author Simon Horne.
// */
//public class Log
//{

//    /**
//     * A convolution operator.
//     */
//    Convolution convolution;
//    /**
//     * An array representing the input image.
//     */
//    int[] input;
//    /**
//     * An array representing the output image.
//     */
//    int[] output;
//    /**
//     * The input image width.
//     */
//    public int width;
//    /**
//     * The input image height.
//     */
//    public int height;
//    /**
//     * The output image width.
//     */
//    public int width2;
//    /**
//     * The output image height.
//     */
//    public int height2;
//    /**
//     * The 2D array representing the laplacian of gaussian kernel.
//     */
//    double[][] logKernel;
//    /**
//     * The 2D array representing the input image.
//     */
//    double[][] input2D;
//    /**
//     * The 2D array representing the input image.
//     */
//    double[][] output2D;
//    /**
//     * The user selected theta value.
//     */
//    double theta;
//    /**
//     * The user selected kernel size.
//     */
//    int kernelSize;

//    /**
//     * Constructor that generates the kernel from the kernel size and theta.
//     *
//     * @param k The kernel size.
//     * @param t the theta value.
//     */
//    public Log(int k, double t){
//    convolution = new Convolution();
//    kernelSize = k;
//    theta = t;
//    logKernel = new double [k][k];
//    generateKernel();
//  }

//    /**
//     * Boolean tests for valid kernel construction from the kernel size and theta.
//     *
//     * @param t the theta value.
//     */
//    public boolean kernelValid(double t)
//    {
//        double sum = 0;
//        double max = logKernel[0][0];
//        for (int j = 0; j < kernelSize; ++j)
//        {
//            for (int i = 0; i < kernelSize; ++i)
//            {
//                //if (j == i)
//                //System.out.println(logKernel[i][j]);
//                sum = sum + logKernel[i][j];
//            }
//        }
//        //System.out.println("Max "+max);
//        //System.out.println("Sum "+sum);
//        if (sum > 0.1 || sum < -0.1 || t <= 0.5 || (t / kernelSize) > 0.09)
//        {
//            // too far from a good value
//            return false;
//        }
//        else
//        {
//            // adjust values slightly to get zero sum
//            double delta = sum / (kernelSize * kernelSize);
//            for (int j = 0; j < kernelSize; ++j)
//            {
//                for (int i = 0; i < kernelSize; ++i)
//                {
//                    logKernel[i][j] = logKernel[i][j] - delta;
//                }
//            }
//            return true;
//        }
//    }


//    /**
//     * Takes x and y coordinates and calculates the kernel element at that point.
//     *
//     * @param x The x coordinate.
//     * @param y The y coordinate.
//     * @return The kernel element.
//     */
//    double logElement(int x, int y)
//    {
//        double g = 0;
//        for (double ySubPixel = y - 0.5; ySubPixel < y + 0.55; ySubPixel += 0.1)
//        {
//            for (double xSubPixel = x - 0.5; xSubPixel < x + 0.55; xSubPixel += 0.1)
//            {
//                double s = -((xSubPixel * xSubPixel) + (ySubPixel * ySubPixel)) /
//                  (2 * theta * theta);
//                g = g + (1 / (Math.PI * Math.pow(theta, 4))) *
//                  (1 + s) *
//                  Math.pow(Math.E, s);
//            }
//        }
//        g = -g / 121;
//        //System.out.println(g);
//        return g;
//    }
//    /**
//     * Generates the kernel from the current theta and kernel size.
//     */
//    void generateKernel()
//    {
//        for (int j = 0; j < kernelSize; ++j)
//        {
//            for (int i = 0; i < kernelSize; ++i)
//            {
//                int x = (-kernelSize / 2) + i;
//                int y = (-kernelSize / 2) + j;
//                logKernel[i][j] = logElement(x, y);
//            }
//        }
//    }

//    /**
//     * Takes an input image and returns the output image after applying the
//     * laplacian of gaussian operator.
//     *
//     * @param input The input image integer array.
//     * @param width The image width.
//     * @param height The image height.
//     * @return The output image integer array.
//     */
//    public int[] log_image(int[] input, int width, int height,
//                double scale, double offset)
//    {

//        input = convolution.convolution_image(input, width, height,
//                          logKernel, kernelSize, kernelSize,
//                          scale, offset);
//        //System.out.println(scale+" "+offset);
//        return input;
//    }
//}

